#include "Layout_Assistant.h"
#include "xVMRelationStruct.h"
#include <deque>
#include "Dynamic_Dialog.h"
#include <sstream>

BOOL CALLBACK ExpDialog( HWND, UINT, WPARAM, LPARAM);
#define BLANK " "

extern HINSTANCE _hInst ;  // this instance is defined in DIVA_MAIN
extern HWND _hWnd ;        // this instance is defined in DIVA_Application
//----------------
extern int maxNum;         //
extern int maxLevel;       // ExpDialog使用
extern string names;       //
extern bool bCancel;       //
extern bool bAutoApply ; //
//----------------
//----------------
int numCount;              // 深度優先展開的遞迴使用
int levelCount;            //
//----------------

Layout_Assistant* Layout_Assistant::lyAst = NULL;

Layout_Assistant::Layout_Assistant(){
}

Layout_Assistant* Layout_Assistant::getInstance(){
	if(lyAst == NULL)
		lyAst = new Layout_Assistant();
	return lyAst;
}
/** set the global variable bAutoApply (defined in ExpDialog.cpp) */
bool Layout_Assistant::getSettingAutoExplore() { return bAutoApply ; } 
void Layout_Assistant::setSettingAutoExplore(bool b) {  bAutoApply = b ; }
//展開的"門面"

void Layout_Assistant::expand(DIVA_VM* vm, bool autoexplore){
	numCount = 0;
	levelCount = 0;	
	if (autoexplore == false)  {
		/*TODO: change to Qt dialog*/
		//DialogBox( _hInst, "EXPLORE_DIALOG", _hWnd, (DLGPROC)ExpDialog);
		vm = xVMRelationStruct::getInstance()->VMRS_toCompositeRootVM(vm);
		if(!bCancel) {
			d_expand(vm);
		  _startvm = vm ;
		}
	} else {
		vm = xVMRelationStruct::getInstance()->VMRS_toCompositeRootVM(vm);
		assert(vm== _startvm);
		d_expand(_startvm);
	}

	

	
}

std::vector<std::string> strSplit(std::string str, std::string delim)
{
	int cutAt;

	std::vector<std::string> results;

	while( (cutAt = str.find_first_of(delim)) != str.npos )
	{
		if(cutAt > 0)
		{
			results.push_back(str.substr(0,cutAt));
		}
		str = str.substr(cutAt+1);
	}
	if(str.length() > 0)
	{
		results.push_back(str);
	}

	return results;
}
//比對使用者輸入的名稱與VM變數名稱，符合就回傳true
bool checkName(DIVA_VM* vm){
	
	string valName;
	valName = vm->get_vm_name(); // it will only works if name inport is linked
	vector<string> names_vec;
	vector<string>::iterator itr ;
	string name;

	if(names=="")
		return true;

	names_vec = strSplit(names, BLANK); // names is a global variable defined
		                                                                      // in ExpDialog.cpp
	for (itr = names_vec.begin(); itr != names_vec.end(); itr++) {
		name = (*itr);
		if(name == valName)
			return true;
	}

	return false;
	/*
	string valName;
	valName = xVMRelationStruct::getInstance()->get_wopName(vm);
	vector<string> names_vec;
	vector<string>::iterator itr ;
	string name;

	if(names=="")
		return true;

	names_vec = strSplit(names, BLANK);
	for (itr = names_vec.begin(); itr != names_vec.end(); itr++) {
		name = (*itr);
		if(name == valName)
			return true;
	}

	return false;
	*/
}

//深度優先展開
void Layout_Assistant::d_expand(DIVA_VM* vm,int nc,int lc){
	numCount = nc;
	levelCount = lc;
	deque<DIVA_VM *> ret;
	vector<DIVA_VM *> chdn ;
	vector<DIVA_VM*> exist_vms;
	vector<DIVA_VM *>::iterator itr ;
	deque<DIVA_VM *>::iterator itr2 ;
	DIVA_VM * p;

	chdn = xVMRelationStruct::getInstance()->get_subVMs(vm);
	ret.push_back(vm);
	
	// since we only click on reference VM 
	for (itr = chdn.begin(); itr != chdn.end(); itr++) {
		p = (*itr);		
		if(p->getVMType() != "reference") 
			continue;
		if(!checkName(p))   // compare p with the names input in Explore_Dialog
			continue;
		if(maxNum>0 && numCount >= maxNum) return;

		ReferenceVM* refp = ((ReferenceVM*)p);

		refp->VMPicked(0,0,0);

		if(xVMRelationStruct::getInstance()->isPointedNULL(refp)) continue;

		DIVA_VM* son = xVMRelationStruct::getInstance()->get_pointedVM(refp);

		numCount++;
		ret.push_back(son);
	}
	exist_vms.insert(exist_vms.end(),ret.begin(),ret.end());

	ret.pop_front();

	levelCount++;
	if(maxLevel>0 && levelCount>=maxLevel)
		return;

	for (itr2 = ret.begin(); itr2 != ret.end(); itr2++) {	
		p = (*itr2);
		d_expand(p,numCount,levelCount);
	}
	/*Basic_Dynamic_lyvm* lyvm = layoutLibrary::getInstance()->getCurrentEnabledDynamicLy();
	if(exist_vms.size() != 0 && lyvm != NULL){
		lyvm->layout(exist_vms);
	}*/
}
